"""
The gorg (graph of Rauzy Graphs).

    An infinite graph is not a computer object so this library add tools to
    approach this object. Some constrained gorg are finite. The possible
    constraint are of two types :
        * constraint on the second difference of the complexity function (or on
        the total valency). This can be a lesser than condition (finite graph), 
        greater than condition (infinite graph) or an equal condition (finite
        graph).
        * constraint on possible bifurcations.
    
    The vertices of this graph are the strongly connected oriented graph with
    total valency on each vertex greater than 2 (this means that a vertex is
    always a topological singularity).

    The edges of this graph are the possible bifurcations from one graph to
    another (always a lot of possibilities).

    Everything is organized by complexity level and level means a given linear
    complexity.

    TODO:
        In SAGE all those must be uniq instances.
"""

import shape_of_rauzy_graph as srg


class Gorg_n(srg.nx.MultiDiGraph):
    """
    The gorg relative to fixed linear complexity graph.

        This object is like a finite graph but is in fact a part of the
        inifinite gorg graph constrained by staying on the same level. For
        example, if you ask :
            sage : G = Gorg_n(4)
            sage : G.successors(G0)
        the response will be only considered in the level 4.
    """
    pass


class Gorg_lesser_than_n(srg.nx.MultiDiGraph):
    """
    The gorg relative to maximum linear complexity graph.

        Be prudent, a Gorg_lesser_than_n is always a pointer to a part of the
        general gorg. There always exists instance of the gorg and uniq. For
        freeing the space occuped by the gorg, you can do :
            sage : gorg.clear() # or something like that
        
        This is a finite graph but computed on demand. You can get the whole
        graph by doing the following trick :
            sage : G = Gorg_n(4)  # the complexity classes less than 4n + k
            sage : G.compute_all()
    """
    pass
            

class Gorg_greater_than_n(srg.nx.MultiDiGraph):
    """
    The gorg relative to minimal linear complexity graph.

        This is an infinite graph and portion of the graph are computed on
        demand.
    """
    pass


class Gorg(srg.nx.MultiDiGraph):
    """
    The gorg.

        The graph is stratified by linear complexity. And each level is
        stratified by the number of vertices and then by valencies of each of
        those vertices.

        vertex = shape of Rauzy Graph
        edge = possible bifurcation
    """

    def __init__(self):
        """
        Constructor.
        """
        pass
        
    def compute_level(self, n):
        """
        Compute the nth level.

            Beware, this command should take a lot of time.
        """
        pass

    def compute_up_to_level(self, n):
        """
        Compute the levels less than n
        """
        pass

    def level(self, level):
        """
        Return the gorg corresponding to the level.

        INPUT:
            level -- an integer
        """
        pass

    def successors(self, node, choice=False):
        """
        Return the successors of the node.
        (i.e. compute all choices of possible deleted choices)

        INPUT:
            node -- a node in the graph
            choice -- boolean which indicate if the results contains choice
        """
        pass

    def constrained_successors(self, node, choice=False):
        """
        Return the successors of the node.
        """
        pass
